﻿// Shader-Based-Image-Processing (SBIP)
// http://code.google.com/p/sbip/
//
// Copyright © Frank Nagl, 2009-2010
// admin@franknagl.de
//
namespace SBIP.Filter
{
    using System;

    /// <summary>
    /// Sepia filter - old brown photo.
    /// </summary>
    /// <remarks><para>The filter makes an image look like an old brown photo. The main
    /// idea of the algorithm:
    /// <list type="bullet">
    /// <item>transform to YIQ color space;</item>
    /// <item>modify it;</item>
    /// <item>transform back to RGB.</item>
    /// </list></para>
    /// 
    /// <para>
    /// <b>1) RGB -> YIQ</b>:
    /// <code lang="none">
    ///	Y = 0.299 * R + 0.587 * G + 0.114 * B
    ///	I = 0.596 * R - 0.274 * G - 0.322 * B
    ///	Q = 0.212 * R - 0.523 * G + 0.311 * B
    ///	</code>
    ///	</para>
    ///	
    /// <para>
    /// <b>2) update</b>:
    /// <code lang="none">
    ///	I = 51
    ///	Q = 0
    ///	</code>
    ///	</para>
    ///	
    /// <para>
    ///	<b>3) YIQ -> RGB</b>:
    /// <code lang="none">
    ///	R = 1.0 * Y + 0.956 * I + 0.621 * Q
    ///	G = 1.0 * Y - 0.272 * I - 0.647 * Q
    ///	B = 1.0 * Y - 1.105 * I + 1.702 * Q
    ///	</code>
    ///	</para>
    ///	
    /// <para>Sample usage:</para>
    /// <code>
    /// Bitmap image = new Bitmap( "cathedral.jpg" );
    ///
    /// // 1. Offline rendering of images
    /// // create Processor, used as rendering framework
    /// Processor processor = new Processor( );
    /// // starts Processor
    /// processor.Begin( image );
    /// // create Sepia filter
    /// Sepia filter = new Sepia( );
    /// processor.Filter = filter;
    /// // apply the filter, render to bitmap  
    /// Bitmap resultImage = processor.RenderToBitmap( );
    /// resultImage.Save( "Sepia.jpg", ImageFormat.Jpeg );
    /// // apply the filter, render to texture
    /// // Texture2D resultTexture = processor.RenderToTexture( );
    /// processor.End( );
    ///  
    /// // 2. Online rendering of videos or images
    /// // create any windows control for rendering in
    /// Form myForm = new Form
    /// {
    ///     Width = 1280,
    ///     Height = 720
    /// };
    /// // starts Processor
    /// processor.Begin( "Video.avi", myForm );
    /// // create Sepia filter
    /// filter = new Sepia( );
    /// processor.Filter = filter;
    /// // apply the filter
    /// myForm.Show( );
    /// while ( myForm.Created )
    /// {
    ///     processor.Render( );
    ///     Application.DoEvents( );
    /// }
    /// processor.End( );
    /// </code>
    /// 
    /// <para><b>Initial image:</b></para>
    /// <img src="../../Cathedral.jpg" width="500" height="338" />
    /// <para><b>Result image:</b></para>
    /// <img src="../../Sepia.jpg" width="500" height="338" />
    /// </remarks>
    public sealed class Sepia : BaseFilter
    {
        #region effect properties
        private float q;
        /// <summary>Q coefficient of YIQ color space. Default: 0.0</summary> 
        public float Q
        {
            get { return q; }
            set
            {
                if (Effect == null)
                    throw new ArgumentException("Q" + InitMsg);

                q = value;
                Effect.Parameters["Q"].SetValue(value);
            }
        }

        private float i;
        /// <summary>I coefficient of YIQ color space. Default: 0.2 (= 51 / 255).</summary>
        public float I
        {
            get { return i; }
            set
            {
                if (Effect == null)
                    throw new ArgumentException("I" + InitMsg);

                i = value;
                Effect.Parameters["I"].SetValue(value);
            }
        }
        #endregion effect properties

        /// <summary>
        /// Initializes a new instance of the <see cref="Sepia"/> class.
        /// </summary>
        public Sepia() : base("Sepia") { }

        /// <summary>
        /// Defines the Q and I coefficients of the sepia algorithm.
        /// </summary>
        protected override void PostInit()
        {
            Q = 0.0f;
            I = 0.2f; // = 51 / 255.0f;
        }
    }
}
